﻿using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace Common
{
    public class AttachPropertyEx
    {

        #region TextBox


        /// <summary>
        /// 目前HasText是可读可写的，很明显它是一个状态只需要可读就行了
        /// 因此需要用到DependencyPropertyKey
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool GetHasText(DependencyObject obj)
        {
            return (bool)obj.GetValue(HasTextProperty);
        }

        public static void SetHasText(DependencyObject obj, bool value)
        {
            obj.SetValue(HasTextPropertyKey, value);
        }


        public static readonly DependencyProperty HasTextProperty; //只能构造注入
        static AttachPropertyEx()
        {
            HasTextProperty = HasTextPropertyKey.DependencyProperty;
        }
        //public static readonly DependencyProperty HasTextProperty = HasTextPropertyKey.DependencyProperty;
        //我们需要一个去监听TextBox的文本的变化，如果直接放在当前属性的回调事件中，就无限循环触发了。所以需要另外一个属性去开启监听

        public static readonly DependencyPropertyKey HasTextPropertyKey =
        DependencyProperty.RegisterAttachedReadOnly("HasText", typeof(bool), typeof(AttachPropertyEx), new PropertyMetadata(false));

        public static bool GetMoit(DependencyObject obj)
        {
            return (bool)obj.GetValue(MoitProperty);
        }

        public static void SetMoit(DependencyObject obj, bool value)
        {
            obj.SetValue(MoitProperty, value);
        }

        // Using a DependencyProperty as the backing store for Moit.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MoitProperty =
            DependencyProperty.RegisterAttached("Moit", typeof(bool), typeof(AttachPropertyEx), new PropertyMetadata(false, MoitCallBack));

        private static void MoitCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is not TextBox box)
            {
                throw new NotImplementedException();
            }
            if ((bool)e.NewValue)
            {
                box.TextChanged += TextBoxChange;
                SetHasText(box, !string.IsNullOrEmpty(box.Text));//解决首次不触发问题
            }
            else
            {
                box.TextChanged -= TextBoxChange;
            }
        }

        private static void TextBoxChange(object sender, TextChangedEventArgs e)
        {
            var textBox = sender as TextBox;
            SetHasText(textBox, !string.IsNullOrEmpty(textBox.Text));
        }

        #region CommandEx

        public static ICommand GetCommandEx(DependencyObject obj)
        {
            return (ICommand)obj.GetValue(CommandExProperty);
        }

        public static void SetCommandEx(DependencyObject obj, ICommand value)
        {
            obj.SetValue(CommandExProperty, value);
        }

        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CommandExProperty =
            DependencyProperty.RegisterAttached("CommandEx", typeof(ICommand), typeof(AttachPropertyEx), new PropertyMetadata(OnTextBoxItemSelectCommand));

        private static void OnTextBoxItemSelectCommand(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var element = d as TextBox;
            element.TextChanged += Element_ItemSelecting;
        }
        private static void Element_ItemSelecting(object sender, EventArgs e)
        {
            var element = sender as TextBox;
            var command = (ICommand)element.GetValue(CommandExProperty);
            command?.Execute(element.Text);
        }
        #endregion
        #endregion

        #region Label
        public static ICommand GetLabelCommand(DependencyObject obj)
        {
            return (ICommand)obj.GetValue(LabelCommandProperty);
        }

        public static void SetLabelCommand(DependencyObject obj, ICommand value)
        {
            obj.SetValue(LabelCommandProperty, value);
        }

        public static readonly DependencyProperty LabelCommandProperty =
            DependencyProperty.RegisterAttached("LabelCommand", typeof(ICommand), typeof(AttachPropertyEx), new PropertyMetadata(OnLabelCommand));

        private static void OnLabelCommand(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var element = d as Label;
            element.MouseLeftButtonUp += OnLabel_Execute;
        }
        private static void OnLabel_Execute(object sender, EventArgs e)
        {
            var element = sender as Label;
            var command = (ICommand)element.GetValue(LabelCommandProperty);
            command?.Execute(null);
        }
        #endregion
    }
}
